package core

import "sync"

// 世界管理模块, 将Player模块与AOI模块封装

type WorldManager struct {
	AOI         *AOIManager       // 当前世界的AOIManager
	Players     map[int32]*Player // 当前世界的Players集合
	PlayersLock sync.RWMutex      // Players读写锁
}

// 全局暴露一个WorldManager模块对象
var WMObj *WorldManager

// 初始化世界
func init() {
	WMObj = &WorldManager{
		AOI:     NewAOIManager(AOI_MIN_X, AOI_MAX_X, AOI_CNT_X, AOI_MIN_Y, AOI_MAX_Y, AOI_CNT_Y),
		Players: make(map[int32]*Player),
	}
}

// 添加Player
func (wm *WorldManager) AddPlayer(player *Player) {
	wm.PlayersLock.Lock()
	defer wm.PlayersLock.Unlock()
	wm.Players[player.Pid] = player
	gid := wm.AOI.GetGIDByPos(player.X, player.Z)
	wm.AOI.AddPlayerIDToGrid(int(player.Pid), gid)
}

// 删除Player
func (wm *WorldManager) RemovePlayer(player *Player) {
	wm.PlayersLock.Lock()
	defer wm.PlayersLock.Unlock()
	delete(wm.Players, player.Pid)
	gid := wm.AOI.GetGIDByPos(player.X, player.Z)
	wm.AOI.RemovePlayerIDToGrid(int(player.Pid), gid)
}

// 删除Player, 通过pid
func (wm *WorldManager) RemovePlayerByPid(pid int32) {
	wm.PlayersLock.Lock()
	defer wm.PlayersLock.Unlock()
	delete(wm.Players, pid)
	player := wm.Players[pid]
	gid := wm.AOI.GetGIDByPos(player.X, player.Z)
	wm.AOI.RemovePlayerIDToGrid(int(pid), gid)
}

// 返回Player, 通过Pid
func (wm *WorldManager) GetPlayerByPid(pid int32) *Player {
	wm.PlayersLock.RLock()
	defer wm.PlayersLock.RUnlock()
	return wm.Players[pid]
}

// 返回Players
func (wm *WorldManager) GetAllPlayers() []*Player {
	wm.PlayersLock.RLock()
	defer wm.PlayersLock.RUnlock()
	players := make([]*Player, 0, len(wm.Players))
	for _, p := range wm.Players {
		players = append(players, p)
	}
	return players
}
